package com.smart.community.common.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.smart.community.common.base.ex.BaseException;
import com.smart.community.common.base.result.ResultStatus;
import com.smart.community.common.base.utils.CommonBeanutils;
import com.smart.community.common.common.qo.QueryConditionsQo;
import com.smart.community.common.common.qo.SysUserQo;
import com.smart.community.common.common.vo.SysUserVo;
import com.smart.community.common.entity.OtherInformation;
import com.smart.community.common.entity.SysUser;
import com.smart.community.common.mapper.OtherInformationMapper;
import com.smart.community.common.mapper.SysUserMapper;
import com.smart.community.common.mapper.UserDataMapper;
import com.smart.community.common.service.SysUserService;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.subject.Subject;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;

import javax.annotation.Resource;

/**
 * @author : 子未语
 * @date : 2024/1/14 10:08
 */
@Service
@Slf4j
public class SysUserServiceImpl implements SysUserService {

    @Resource
    private UserDataMapper userDataMapper;

    @Resource
    private OtherInformationMapper otherInformationMapper;

    @Resource
    private SysUserMapper sysUserMapper;

    @Override
    public IPage<SysUserVo> searchAll(QueryConditionsQo queryConditionsQo, int page, int size) {
        // 创建分页对象
        Page<SysUser> sysUserPage = new Page<>(page, size);
        QueryWrapper<SysUser> queryWrapper = new QueryWrapper<>();
        // 根据 SysUserQo 的属性设置查询条件
        if (queryConditionsQo != null) {
            if (!ObjectUtils.isEmpty(queryConditionsQo.getKey())) {
                queryWrapper.like(SysUser.COL_SYS_USER_NAME, queryConditionsQo.getKey());
            }
            if (queryConditionsQo.getUserId() != 0) {
                queryWrapper.eq(SysUser.COL_SYS_USER_ID, queryConditionsQo.getUserId());
            }
            if (queryConditionsQo.getUserTypeId() != 0) {
                queryWrapper.eq(SysUser.COL_USER_TYPE_ID, queryConditionsQo.getUserTypeId());
            }
            if (queryConditionsQo.getDelStatus() > 0) {
                queryWrapper.eq(SysUser.COL_DEL_STATUS, queryConditionsQo.getDelStatus());
            }
        }
        // 自定义分页查询
        return userDataMapper.selectAll(sysUserPage, queryWrapper);
    }

    @Override
    public SysUserVo querySingle(Integer id) {
        return userDataMapper.selectById(id);
    }


    @Override
    @Transactional(timeout = 3000, rollbackFor = RuntimeException.class)
    public Boolean addSysUser(SysUserQo sysUserQo) {
        try {
            // 数据转换
            SysUser sysUser = CommonBeanutils.convertTo(sysUserQo, SysUser::new);
            OtherInformation otherInformation = CommonBeanutils.convertTo(sysUserQo.getOtherInformationQo(), OtherInformation::new);
            // 如果数据转换异常则抛出异常报错
            if (sysUser == null || otherInformation == null) {
                throw new BaseException(ResultStatus.INSERT_FAULT);
            }
            // 插入 SysUser
            int userInsertCount = userDataMapper.insertSysUser(sysUser);
            if (userInsertCount == 0) {
                throw new BaseException(ResultStatus.INSERT_FAULT);
            }
            otherInformation.setSysUserId(sysUser.getSysUserId());
            // 插入 OtherInformation
            int infoInsertCount = otherInformationMapper.insert(otherInformation);
            if (infoInsertCount == 0) {
                throw new BaseException(ResultStatus.INSERT_FAULT);
            }
            // 如果一切正常，则返回 true
        } catch (Exception e) {
            log.info(e.getMessage());
            throw new BaseException(ResultStatus.INSERT_FAULT);
        }
        return true;
    }


    @Override
    @Transactional(timeout = 3000, rollbackFor = RuntimeException.class)
    public Boolean modify(SysUserQo sysUserQo) {
        try {
            // 数据转换
            SysUser sysUser = CommonBeanutils.convertTo(sysUserQo, SysUser::new);
            OtherInformation otherInformation = CommonBeanutils.convertTo(sysUserQo.getOtherInformationQo(), OtherInformation::new);
            // 如果数据转换异常则抛出异常报错
            if (sysUser == null || otherInformation == null) {
                throw new BaseException(ResultStatus.INSERT_FAULT);
            }
            // 修改 SysUser
            int userInsertCount = userDataMapper.updateById(sysUser);
            if (userInsertCount == 0) {
                throw new BaseException(ResultStatus.INSERT_FAULT);
            }
            // 创建条件构造器,用于进行判断修改的数据
            QueryWrapper<OtherInformation> otherInformationQueryWrapper = new QueryWrapper<>();
            // 修改 OtherInformation
            otherInformationQueryWrapper.eq(OtherInformation.COL_SYS_USER_ID, sysUser.getSysUserId());
            int infoInsertCount = otherInformationMapper.update(otherInformation, otherInformationQueryWrapper);
            if (infoInsertCount == 0) {
                throw new BaseException(ResultStatus.INSERT_FAULT);
            }
            // 如果一切正常，则返回 true
        } catch (Exception e) {
            log.info(e.getMessage());
            throw new BaseException(ResultStatus.INSERT_FAULT);
        }
        return true;
    }


    @Override
    public int del(Integer id) {
        int i = sysUserMapper.deleteById(id);
        if (i == 0) {
            return userDataMapper.startUsing(id);
        }
        return i;
    }

    @Override
    public String login(String username, String password) {
        // 通过账户密码获取到subject对象
        Subject subject = SecurityUtils.getSubject();
        // 调用安全认证的login方法
        try {
            subject.login(new UsernamePasswordToken(username, password));
        } catch (UnknownAccountException | IncorrectCredentialsException uae) {
            throw new BaseException(ResultStatus.WRONG_USER_NAME_OR_PASSWORD);
        } catch (LockedAccountException lae) {
            throw new BaseException(ResultStatus.ABNORMAL_USER_STATUS);
        } catch (AuthenticationException ae) {
            throw new BaseException(ResultStatus.LOGIN_FAILED);
        }
        return SecurityUtils.getSubject().getSession(false).getId().toString();
    }

    @Override
    public SysUser getUserInfo(String username) {
        return sysUserMapper.selectByUsername(username);
    }
}
